use salvo::prelude::*;
use crate::service::conn;
use crate::service::rbac::{user_role::UserRoleService};
use crate::service::rbac::role_menu::RoleMenuService;

#[handler]
pub async fn permission_check(
    req: &mut Request,
    res: &mut Response,
    depot: &mut Depot,
    ctrl: &mut FlowCtrl
) {
    // 获取当前用户ID
    let user_id = match depot.get::<crate::hoops::jwt::JwtClaims>("jwt_claims") {
        Ok(claims) => claims.uid().to_string(),
        Err(_) => {
            res.status_code(StatusCode::UNAUTHORIZED);
            ctrl.skip_rest();
            return;
        }
    };

    // 获取当前请求路径作为权限标识
    let permission_code = req.uri().path().to_string();

    let tenant_id: i64 = match crate::utils::tenant::get_tenant_id(req) {
        Ok(id) => id as i64,
        Err(_) => {
            res.status_code(StatusCode::BAD_REQUEST);
            ctrl.skip_rest();
            return;
        }
    };
    
    // 获取用户所有角色
    let roles = match UserRoleService::find_roles_by_user(conn(), &user_id, tenant_id).await {
        Ok(roles) => roles,
        Err(_) => {
            res.status_code(StatusCode::INTERNAL_SERVER_ERROR);
            ctrl.skip_rest();
            return;
        }
    };

    // 检查用户是否有权限
    let mut has_permission = false;
    for role_id in roles {
        if let Ok(menus) = RoleMenuService::find_menus_by_role(conn(), &role_id, tenant_id).await {
            if menus.iter().any(|p| permission_code.starts_with(p)) {
                has_permission = true;
                break;
            }
        }
    }

    if !has_permission {
        res.status_code(StatusCode::FORBIDDEN);
        ctrl.skip_rest();
    }
}

pub fn permission_hoop() -> impl Handler {
    permission_check
}
